import axios from 'axios'
import store from '@/store'
import storage from 'store'
import notification from 'ant-design-vue/es/notification'
import { VueAxios } from './axios'
import { ACCESS_TOKEN, REFRESH_TOKEN } from '@/store/mutation-types'
import { login } from '@/api/login'
import qs from 'qs'

// 创建 axios 实例
const request = axios.create({
  // API 请求的默认前缀
  baseURL: process.env.VUE_APP_API_BASE_URL,
  timeout: 1000 * 60 * 60, // 请求超时时间
  customCode: false, // 用与自定义判断code码状态
})
let showMsg = true
// 是否正在刷新
let isRefreshing = false
// 数据报错请求队列
let requests = []

// 异常拦截处理器
const errorHandler = (error) => {
  console.log(error)
  if (error.response) {
    // const data = error.response.data
    // 从 localstorage 获取 token
    // const token = storage.get(ACCESS_TOKEN)
    // if (error.response.status === 403) {
    //   notification.error({
    //     message: 'Forbidden',
    //     description: data.message
    //   })
    // }
    if (error.response.status === 401) {
      if (showMsg) {
        showMsg = false
        notification.error({
          message: '账号已离线',
          description: '您的账号已离线，请重新登录',
          style: {
            color: '#000',
          },
        })
        setTimeout(() => {
          storage.remove(ACCESS_TOKEN)
          store.commit(ACCESS_TOKEN, '')
          storage.remove(REFRESH_TOKEN)
          window.location.href = '/login'
          showMsg = true
        }, 5000)
      }
      return
    }
    // notification.error({
    //   message: '请求发生错误',
    //   description: `错误码：${error.response.status}`,
    //   style: {
    //     color: '#000',
    //   },
    // })
  } else if (error.request) {
    notification.error('请求超时，请刷新重试')
  } else {
    // notification.error({
    //   message: '请求失败',
    //   description: `错误码：${error.response.status}`,
    //   style: {
    //     color: '#000',
    //   },
    // })
  }
  return Promise.reject(error)
}

// request interceptor
request.interceptors.request.use((config) => {
  const token = storage.get(ACCESS_TOKEN)
  const uid = store.getters.userid
  // 如果 token 存在
  // 让每个请求携带自定义 token 请根据实际情况自行修改
  if (token) {
    config.headers['Authorization'] = token
  }
  // 如果token、uid存在，则在每个http请求头上携带userid
  if (token && uid) {
    config.headers['GF'] = uid
  }
  if (config['setJson']) {
    config.headers['Content-Type'] = 'application/json'
  }
  return config
}, errorHandler)

// response interceptor
request.interceptors.response.use((response) => {
  const config = response.config
  // if (response.data.code == 200) {
  //   this.$notification[type]({
  //     message: '失败',
  //     description: '提交失败',
  //   })
  // }
  if (response.data.code && response.data.code !== 200 && !config.customCode && response.data.code !== 201) {
    // 如果响应code码等于209 视为当前toke过期，重新调用登录接口刷新token
    if (response.data.code === 209) {
      if (!isRefreshing) {
        isRefreshing = true
        storage.remove(ACCESS_TOKEN)
        store.commit('SET_TOKEN', '')
        return login(
          qs.stringify({
            grant_type: 'refresh_token',
            refresh_token: storage.get(REFRESH_TOKEN),
          })
        )
          .then((res) => {
            const successToken = res.token_type + ' ' + res.access_token
            const refreshToken = res.refresh_token
            store.commit('SET_TOKEN', successToken)
            storage.set(ACCESS_TOKEN, refreshToken)
            storage.set(REFRESH_TOKEN, refreshToken)
            requests.forEach((cb) => cb(successToken))
            requests = []
            return request(config)
          })
          .catch(() => {
            storage.remove(ACCESS_TOKEN)
            store.commit('SET_TOKEN', '')
            storage.remove(REFRESH_TOKEN)
            window.location.href = '/login'
          })
          .finally(() => {
            isRefreshing = false
          })
      } else {
        // 正在刷新token，返回一个未执行resolve的promise
        return new Promise((resolve) => {
          requests.push((token) => {
            config.headers['Authorization'] = token
            resolve(request(config))
          })
        })
      }
    }
    notification.error({
      message: '请求发生了错误',
      description: `${response.data.msg}。`,
      style: {
        color: '#000',
      },
    })
    return Promise.reject(new Error(response.data.msg || 'Error'))
  }
  return response.data
}, errorHandler)

const installer = {
  vm: {},
  install(Vue) {
    Vue.use(VueAxios, request)
  },
}

export default request

export { installer as VueAxios, request as axios }
